package com.example.websocket.excel.util;

import javax.crypto.*;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

public class AESCrypt {
	/**
	 * 加密模式处理对象
	 */
	private static Cipher encrypt;
	/**
	 * 解密模式处理对象
	 */
	private static Cipher decrypt;
	/**
	 * 密钥对象
	 */
	private static Key key;
	/**
	 * 加密字符串转换字节编码
	 */
	private final static String DEFALUT_ENCODING = "utf-8";
	/**
	 * 加密字符串转换字节编码
	 */
	private final static String DEFALUT_KEY = "jdy_login.key";
	/**
	 * 将字符串加密
	 * @param newpass 字符串
	 * @return 加密后的字符串
	 */
	public static String encrypt(String newpass) {//加密
		String crypt=null;
		if(newpass!=null){
			try {
				byte[] b = encrypt(newpass.trim().getBytes(DEFALUT_ENCODING));
				crypt = byte2hex(b);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return crypt;
	}
	/**
	 * 将byte字节数组加密
	 * @param cyperText 字节数组
	 * @return 加密后的字节数组
	 */
	public static byte[] encrypt(byte[] cyperText) {//加密
		byte[] b=null;
		if(cyperText!=null){
			try {
				b=createEncrypt().doFinal(cyperText);
			} catch (IllegalBlockSizeException e) {
				e.printStackTrace();
			} catch (BadPaddingException e) {
				e.printStackTrace();
			}
		}
		return b;
	}
	/**
	 * 解密字符串
	 * @param cyperText 字符串
	 * @return 解密后的字符串
	 */
	public static String decrypt(String cyperText) {//解密
		String crypt=null;
		if(cyperText!=null){
			try {
				byte[] b=decrypt(hex2byte(cyperText.trim()));
				if(b == null)
					return cyperText;
				crypt=new String(b, DEFALUT_ENCODING);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return crypt;
	}
	/**
	 * 解密字节数组
	 * @param cyperText 字节数组
	 * @return 解密后的字节数组
	 */
	public static byte[] decrypt(byte[] cyperText) {//解密
		byte[] b=null;
		if(cyperText!=null){
			try {
				b=createDecrypt().doFinal(cyperText);
			} catch (IllegalBlockSizeException e) {
				e.printStackTrace();
			} catch (BadPaddingException e) {
				e.printStackTrace();
			}
		}
		return b;
	}
	/**
	 * 获取文件密钥
	 * @return 密钥对象
	 */
	private static Key getAESKey(){
		if( key == null ){
			try {
				InputStream keyStream = AESCrypt.class.getResourceAsStream("/" + DEFALUT_KEY);
				if(keyStream == null)
					keyStream = AESCrypt.class.getResourceAsStream("../../../../" + DEFALUT_KEY);
				if(keyStream == null)
					throw new FileNotFoundException("密钥文件不存在！");
				ObjectInputStream ois=new ObjectInputStream(keyStream);
				key=(Key)ois.readObject();
			} catch (IOException e) {
				throw new RuntimeException(e);
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
		}
		return key;
	}
	/**
	 * 將字符串传唤成16进制字节数组
	 * @param strhex 字符串
	 * @return 16进制字节数组
	 */
	private static byte[] hex2byte(String strhex) {
		if (strhex == null) {
			return null;
		}
		int l = strhex.length();
		if (l % 2 == 1) {
			return null;
		}
		byte[] b = new byte[l / 2];
		for (int i = 0; i != l / 2; i++) {
			b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),16);
		}
		return b;
	}
	/**
	 * 將16进制字节数组转换成字符串
	 * @param b 16进制字节数组
	 * @return 字符串
	 */
	private static String byte2hex(byte[] b) {
		String stmp = "";
		StringBuffer sbuf=new StringBuffer(b.length*2);
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				sbuf.append("0");
			sbuf.append(stmp);
		}
		return sbuf.toString().toUpperCase();
	}
	/**
	 * 创建加密模式处理对象
	 * @return 密模式处理对象
	 */
	private static synchronized Cipher createEncrypt(){
		if(encrypt==null){
			try {
				encrypt = Cipher.getInstance("AES/ECB/PKCS5Padding");
				encrypt.init(Cipher.ENCRYPT_MODE, getAESKey());
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchPaddingException e) {
				e.printStackTrace();
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			}
		}
		return encrypt;
	}
	/**
	 * 创建解密模式处理对象
	 * @return 解密模式处理对象
	 */
	private static synchronized Cipher createDecrypt(){
		if(decrypt==null){
			try {
				decrypt = Cipher.getInstance("AES/ECB/PKCS5Padding");
				decrypt.init(Cipher.DECRYPT_MODE, getAESKey());
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchPaddingException e) {
				e.printStackTrace();
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			}
		}
		return decrypt;
	}
	
	public static void genKey(String storePath) {
		try {
			KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");  
			keyGenerator.init(128);  
			SecretKey secretKey = keyGenerator.generateKey();
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(storePath));
			out.writeObject(secretKey);
			out.close();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}